﻿using System;
using System.Collections.Generic;

namespace YArchitech.Plumbing
{
	public class HYFluxCal
	{
		public bool CalFiuxData(CalDrainData calDrain)
		{
			if (this.pipeCals == null || this.pipeCals.Count <= 0)
			{
				return false;
			}
			for (int i = 0; i < this.pipeCals.Count; i++)
			{
				double num = 0.0;
				double num2 = 0.0;
				double num3 = 0.0;
				double num4 = 0.0;
				for (int j = 0; j < this.pipeCals[i].upBathroomArray.Count; j++)
				{
					HYBathroom hybathroom = this.pipeCals[i].upBathroomArray[j];
					if (num <= hybathroom.dFluxFlow)
					{
						num = hybathroom.dFluxFlow;
					}
					num2 += (double)hybathroom.nCount * hybathroom.dFluxFlow;
					num3 += num2 * (hybathroom.dPer / 100.0);
					num4 += (double)hybathroom.nCount * hybathroom.dFluxEquivalent;
				}
				if (calDrain.nFormula == 1)
				{
					this.pipeCals[i].Flow = num3;
					if (this.pipeCals[i].Flow < num)
					{
						this.pipeCals[i].Flow = num;
					}
				}
				else
				{
					this.pipeCals[i].Flow = 0.12 * calDrain.dα * Math.Sqrt(num4) + num;
					if (this.pipeCals[i].Flow > num2)
					{
						this.pipeCals[i].Flow = num2;
					}
				}
			}
			return true;
		}

		public void Cal_DN_Grade(HYSystemCal sys, bool bIsDesign)
		{
			if (bIsDesign)
			{
				this.SetPipeBase(sys.Root as HYPipeCal);
			}
			for (int i = 0; i < this.pipeCals.Count; i++)
			{
				HYPipeCal hypipeCal = this.pipeCals[i];
				if (hypipeCal.bIsCal)
				{
					this.DrainDN(ref hypipeCal, bIsDesign);
				}
				else
				{
					this.DrainDN(ref hypipeCal, false);
				}
			}
		}

		public void SetPipeBase(HYPipeCal pipe)
		{
			if (pipe == null)
			{
				return;
			}
			HYBathroom endBathroom = pipe.endBathroom;
			for (int i = 0; i < pipe.subPipeArray.Count; i++)
			{
				this.SetPipeBase(pipe.subPipeArray[i]);
				if (!pipe.bIsCal)
				{
					pipe.nDN = pipe.subPipeArray[i].nDN;
				}
			}
		}

		public void DrainDN(ref HYPipeCal pipe, bool bIsDesign)
		{
			if (!pipe.bIsHorL)
			{
				if (bIsDesign)
				{
					this.GetRiserDNFromQ(ref pipe);
					if (pipe.nDN < pipe.MinDN || pipe.nDN > 10 * pipe.MinDN)
					{
						pipe.nDN = pipe.MinDN;
					}
					pipe.GetDNFromArray();
					return;
				}
			}
			else
			{
				if (bIsDesign)
				{
					int dnfromQGrad = this.GetDNFromQGrad(ref pipe);
					pipe.nDN = dnfromQGrad;
					if (pipe.nDN < pipe.MinDN)
					{
						pipe.nDN = pipe.MinDN;
					}
					if (pipe.nDN < 50)
					{
						pipe.nDN = 50;
					}
					pipe.GetDNFromArray();
					if (pipe.dGrad < 0.0001)
					{
						pipe.dGrad = this.GetGradFromDN(pipe.nDN);
					}
				}
				else
				{
					pipe.dFullness = this.GetFullnessFromDN(pipe.nDN);
					double num = pipe.GetInDN();
					if (num <= 0.0)
					{
						num = (double)pipe.nDN;
					}
					if (pipe.dGrad < 0.0001)
					{
						pipe.dGrad = this.GetGradFromDN(pipe.nDN);
					}
					if (this.GetQFromFullnessGradInDN(pipe.dFullness, pipe.dGrad, num) < pipe.Flow / 1000.0)
					{
						pipe.szNote = "过流能力不够";
					}
				}
				double velocity = pipe.Flow / 1000.0 / this.GetCurA(pipe.GetInDN(), pipe.dFullness);
				pipe.Velocity = velocity;
			}
		}

		public void GetRiserDNFromQ(ref HYPipeCal pipe)
		{
			List<HYRiserRange> riserRange = HYCalSQLData.GetRiserRange();
			riserRange.Sort(new Comparison<HYRiserRange>(HYRiserRange.ComperByDN));
			if (this.nVentilation == 0)
			{
				for (int i = 0; i < riserRange.Count; i++)
				{
					if (pipe.Flow <= riserRange[i].dVentilQ || i == riserRange.Count - 1)
					{
						pipe.nDN = riserRange[i].nDN;
						return;
					}
				}
			}
			else
			{
				for (int i = 0; i < riserRange.Count; i++)
				{
					if (pipe.Flow <= riserRange[i].dNoVentilQ || i == riserRange.Count - 1)
					{
						pipe.nDN = riserRange[i].nDN;
						return;
					}
				}
			}
			pipe.nDN = 50;
		}

		public int GetDNFromQGrad(ref HYPipeCal pipe)
		{
			Dictionary<int, double> dirDNArray = pipe.dirDNArray;
			int num = -1;
			foreach (KeyValuePair<int, double> keyValuePair in dirDNArray)
			{
				num = keyValuePair.Key;
				double fullnessFromDN = this.GetFullnessFromDN(num);
				double value = keyValuePair.Value;
				pipe.dFullness = fullnessFromDN;
				double num2 = pipe.dGrad;
				if (num2 < 1E-05)
				{
					num2 = this.GetGradFromDN(num);
				}
				if (this.GetQFromFullnessGradInDN(fullnessFromDN, num2, value) > pipe.Flow / 1000.0)
				{
					break;
				}
			}
			return num;
		}

		public double GetFullnessFromDN(int dn)
		{
			foreach (HYDrainGradFullness hydrainGradFullness in HYCalSQLData.GetGradFullness(this.calParameter.nMaterType))
			{
				if (dn <= hydrainGradFullness.nDN)
				{
					return hydrainGradFullness.dFullness;
				}
			}
			return 0.7;
		}

		public double GetGradFromDN(int dn)
		{
			List<HYDrainGradFullness> gradFullness = HYCalSQLData.GetGradFullness(this.calParameter.nMaterType);
			double result = 0.0;
			foreach (HYDrainGradFullness hydrainGradFullness in gradFullness)
			{
				result = hydrainGradFullness.dUseGrad;
				if (dn <= hydrainGradFullness.nDN)
				{
					return hydrainGradFullness.dUseGrad;
				}
			}
			return result;
		}

		public double GetQFromFullnessGradInDN(double dFullness, double dGrad, double dInDN)
		{
			double curA = this.GetCurA(dInDN, dFullness);
			double num = 1.0 / this.calParameter.n * Math.Pow(this.GetCurR(dInDN, dFullness), 0.66666666666666663) * Math.Sqrt(dGrad);
			return curA * num;
		}

		public double GetCurA(double dInDN, double dFullness)
		{
			dInDN /= 1000.0;
			double num = dInDN / 2.0;
			double result = num * num * (Math.Acos(1.0 - 2.0 * dFullness) + 2.0 * (2.0 * dFullness - 1.0) * Math.Sqrt(dFullness - dFullness * dFullness));
			double num2 = Math.Acos(Math.Abs(dFullness - 0.5) / 0.5);
			if (dFullness < 0.5)
			{
				result = (num2 - Math.Sin(num2) * Math.Cos(num2)) * num * num;
			}
			else
			{
				result = (Math.PI - num2 + Math.Sin(num2) * Math.Cos(num2)) * num * num;
			}
			return result;
		}

		public double GetCurP(double dInDN, double dFullness)
		{
			dInDN /= 1000.0;
			double num = dInDN / 2.0;
			double num2 = Math.Acos(Math.Abs(dFullness - 0.5) / 0.5);
			double result;
			if (dFullness < 0.5)
			{
				result = 2.0 * num2 * num;
			}
			else
			{
				result = 2.0 * (Math.PI - num2) * num;
			}
			return result;
		}

		public double GetCurR(double dInDN, double dFullness)
		{
			return this.GetCurA(dInDN, dFullness) / this.GetCurP(dInDN, dFullness);
		}

		public double GetCurFullnessFromQGrad(double dQ, double dInDN, double dGrad, double dPrec)
		{
			dQ /= 1000.0;
			double num = 1.0;
			double num2 = 0.001;
			double num3 = (num + num2) / 2.0;
			for (int i = 0; i < 100; i++)
			{
				double curA = this.GetCurA(dInDN, num3);
				double curV_LS = this.GetCurV_LS(dInDN, dGrad, num3);
				double num4 = curA * curV_LS;
				if (Math.Abs(num4 - dQ) <= dPrec)
				{
					return num3;
				}
				if (dQ > num4)
				{
					num2 = num3;
				}
				else
				{
					num = num3;
				}
				num3 = (num + num2) / 2.0;
			}
			return num3;
		}

		public double GetCurV_LS(double dInDN, double dGrad, double dFullness)
		{
			double curA = this.GetCurA(dInDN, dFullness);
			double curP = this.GetCurP(dInDN, dFullness);
			return 1.0 / this.calParameter.n * Math.Pow(curA / curP, 0.66666666666666663) * Math.Pow(dGrad, 0.5);
		}

		public List<HYPipeCal> pipeCals;

		public int nVentilation;

		public HYCalParameter calParameter = new HYCalParameter();
	}
}
